﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Rokae_net
{
    public class RokaeAPI
    {


        /// <summary>
        /// MoveAbsj 执行时需要的数据
        /// </summary>
        public struct rokae_jnttarget_pos
        {
            /// <summary>
            /// 运动参数
            /// </summary>
            public rokae_sdk_motion_param motion_param;           //运动参数
            /// <summary>
            /// 关节数据信息
            /// </summary>
            public rokae_sdk_get_jnt_robot_position jnt_pos;      //关节数据信息

        }


        /// <summary>
        /// 关节位置信息
        /// </summary>
        public struct rokae_sdk_get_jnt_robot_position
        {

            public double j1;     //机器人 1 轴关节角度
            public double j2;     //机器人 2 轴关节角度
            public double j3;     //机器人 3 轴关节角度
            public double j4;     //机器人 4 轴关节角度
            public double j5;     //机器人 5 轴关节角度
            public double j6;     //机器人 6 轴关节角度

        }

        /// <summary>
        /// MoveL，MoveJ 执行时需要的数据
        /// </summary>
        public struct rokae_robtarget_pos
        {

            public int euler_type;                                //读取欧拉 jog 顺规类型 : 0 为使用欧拉角 XYZ 顺规；1 为使用欧拉角 ZYX 顺规；其他为使用四元数规则。（通常为 xyz 规则或四元数规则）
            public rokae_sdk_motion_param motion_param;           //运动参数
            public rokae_sdk_get_rob_robot_position rob_pos;      //笛卡尔空间数据信息

        }

        /// <summary>
        /// 运动参数
        /// </summary>
        public struct rokae_sdk_motion_param
        {
            /// <summary>
            /// 关节速度百分比，取值范围（1~100）
            /// </summary>
            public double per;     //关节速度百分比，取值范围（1~100）
            /// <summary>
            /// TCP 线速度，取值范围（1~7000）
            /// </summary>
            public double tcp;     //TCP 线速度，取值范围（1~7000）
            /// <summary>
            /// 笛卡尔空间转弯区大小 ，取值范围（0~200）
            /// </summary>
            public double iZone;   //笛卡尔空间转弯区大小 ，取值范围（0~200）

        }

        /// <summary>
        /// 笛卡尔空间数据信息
        /// </summary>
        public struct rokae_sdk_get_rob_robot_position
        {

            public double cogx;   //X 坐标
            public double cogy;   //Y 坐标
            public double cogz;   //Z 坐标
            public double q1;     //四元数: q1
            public double q2;     //四元数: q2
            public double q3;     //四元数: q3
            public double q4;     //四元数: q4
            public double a;      // 欧拉角 A
            public double b;      //欧拉角 B
            public double c;      //欧拉角 C
        }


        /// <summary>
        ///  API_MoveLOffSinglePosition()和 API_MoveLOffMutiPosition()函数使用的数据类型
        /// </summary>
        public struct rokae_robtarget_pos_off
        {

            public rokae_robtarget_pos base_rob_pos;     //基于坐标点信息，数据结构为 RokaeRobtargetPos
            public double x_off;                         //基于 base_rob_pos 在 x 方向的偏移量
            public double y_off;                         //基于 base_rob_pos 在 y 方向的偏移量
            public double z_off;                         //基于 base_rob_pos 在 z 方向的偏移量


        }

        /// <summary>
        /// API_GetRobotPosition ()函数使用的数据类型
        /// </summary>
        public struct rokae_sdk_get_robot_position
        {

            public rokae_sdk_get_jnt_robot_position jnt_pos;     //关节位置信息
            public rokae_sdk_get_rob_robot_position rob_pos;     //笛卡尔空间数据信息


        }

        /// <summary>
        /// IO 信息数据
        /// </summary>
        public struct RokaeSDKIOValuePOD
        {

            public Byte pod_name;   //信号对应名字

            public int pod_value;  //信号对应电平,0：低电平；1：高电平

        }



        /// <summary>
        /// 伺服接通，电机上电
        /// </summary>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_MotorOn", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_MotorOn();

        /// <summary>
        /// 初始化，建立连接等初始化操作
        /// </summary>
        /// <param name="ip">ip 地址，点分十进制形式，例如："192.168.3.100"</param>
        /// <param name="port">端口号 0 - 65535</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_Init", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_Init(String ip, int port);

        /// <summary>
        /// 释放函数，执行下电，断开连接操作
        /// </summary>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_Release", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_Release();

        /// <summary>
        /// 查询机械手状态。若异常，返回异常报错信息 (调用 API_GetRobotStatus()函数前，需要先清除示教器界面报警弹框)
        /// </summary>
        /// <param name="msg">状态信息码对应的状态:0：初始化状态,1：电机停止状态,2：电机上电状态,3：常规停止状态,4：紧急停止状态,5：故障状态</param>
        /// <param name="len">错误信息长度</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_GetRobotStatus", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_GetRobotStatus(ref String msg, ref uint len);

        /// <summary>
        /// 启动机械手程序
        /// </summary>
        /// <returns>int : 错误码-- 0，正常；返回值<0，异常，具体待定义</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_StartRobotProgram", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_StartRobotProgram();


        /// <summary>
        /// 停止机械手程序
        /// </summary>
        /// <returns>int : 错误码-- 0，正常；返回值<0，异常，具体待定义</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_StopRobotProgram", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_StopRobotProgram();


        /// <summary>
        /// 设置报警和清除报警，暂时仅支持清除报警功能
        /// </summary>
        /// <param name="value">0，清除报警；1，报警</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_SetAlarmStatus", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_SetAlarmStatus(int value);

        /// <summary>
        /// 复位机械手程序指针
        /// </summary>
        /// <returns>int : 错误码-- 0，正常；返回值<0，异常，具体待定义</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_ResetProgramPointer", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_ResetProgramPointer();


        /// <summary>
        /// 程序指针指到 main 函数第一行
        /// </summary>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_PPtomain", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_PPtomain();



        /// <summary>
        /// 开始执行程序
        /// </summary>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_StartRun", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_StartRun();


        /// <summary>
        /// 暂停运行程序，机器人未下电的情况下，可调用 API_StartRun()、按程序启动按钮或系统 IO 输入启动程序，继续执行未运行结束的点
        /// </summary>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_Stop0", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_Stop0();


        /// <summary>
        ///停止运行程序，未运行结束的点不能继续执行
        /// </summary>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_Stop1", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_Stop1();


        /// <summary>
        /// 急停
        /// </summary>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_EmgStop", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Rokae_API_EmgStop();


        /// <summary>
        /// 设置 IO 信号
        /// </summary>
        /// <param name="msg">设置 DO 信号的参数</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_WriteOutBit", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int API_WriteOutBit(RokaeSDKIOValuePOD msg);


        /// <summary>
        /// 读取 IO 信号
        /// </summary>
        /// <param name="di_name">要读取信号的名字</param>
        /// <param name="name_len">信号名称的长度</param>
        /// <param name="msg">获取信号的信息</param>
        /// <param name="len">获取信息的长度</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_ReadInBit", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int API_ReadInBit(string di_name, int name_len, ref RokaeSDKIOValuePOD msg, ref uint len);


        /// <summary>
        /// 机械手返回初始位置，该初始位置预留在机械手内
        /// </summary>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_HomeMove", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int API_HomeMove();


        /// <summary>
        /// 移动单个 robpos，对应 MoveL/MoveJ 指令
        /// </summary>
        /// <param name="iMoveMode">运动模式，0：MoveJ ； 1：MoveL</param>
        /// <param name="rob_pos">执行 MoveL，MoveJ 时的必须参数</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_MoveLSinglePosition", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int API_MoveLSinglePosition(int iMoveMode, rokae_robtarget_pos rob_pos);


        /// <summary>
        /// 移动多个 robpos，对应 MoveL/MoveJ 指令
        /// </summary>
        /// <param name="iMoveMode">运动模式，0：MoveJ ； 1：MoveL</param>
        /// <param name="rob_pos">执行 MoveL，MoveJ 时的必须参数</param>
        /// <param name="num">点位个数</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_MoveLMutiPosition", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int API_MoveLMutiPosition(int iMoveMode, rokae_robtarget_pos[] jnt_pos, int num);



        /// <summary>
        /// 移动单个 jntpos，对应 moveabsj 指令
        /// </summary>
        /// <param name="jnt_pos">执行 MoveAbsj 时的必须参数</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_MoveAbsjSinglePosition", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int API_MoveAbsjSinglePosition(rokae_jnttarget_pos jnt_pos);


        /// <summary>
        /// 移动多个 jntpos，对应 moveabsj 指令
        /// </summary>
        /// <param name="jnt_pos">执行 MoveAbsj 时的必须参数</param>
        /// <param name="num">点位个数</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_MoveAbsjMutiPosition", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int API_MoveAbsjMutiPosition(rokae_jnttarget_pos[] jnt_pos, int num);


        /// <summary>
        /// 在坐标点的基础上进行偏移
        /// </summary>
        /// <param name="iMoveMode">运动模式，0：MoveJ ； 1：MoveL</param>
        /// <param name="rob_pos">执行 MoveL，MoveJ 时的必须参数</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_MoveLOffSinglePosition", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int API_MoveLOffSinglePosition(int iMoveMode, rokae_robtarget_pos_off rob_pos);


        /// <summary>
        /// 在坐标点的基础上进行偏移
        /// </summary>
        /// <param name="iMoveMode">运动模式，0：MoveJ ； 1：MoveL</param>
        /// <param name="rob_pos">执行 MoveL，MoveJ 时的必须参数</param>
        /// <param name="num">点位个数</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_MoveLOffMutiPosition", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int API_MoveLOffMutiPosition(int iMoveMode, rokae_robtarget_pos_off[] rob_pos, int num);


        /// <summary>
        /// 获取机器人位姿信息
        /// </summary>
        /// <param name="msg">机器人位姿信息</param>
        /// <param name="len">信息长度</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "API_GetRobotPosition", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int API_GetRobotPosition(ref rokae_sdk_get_robot_position msg, ref uint len);


        /// <summary>
        /// 读取信息通用方法，持续保存全局操作的最后一次错误信息
        /// </summary>
        /// <param name="msg">输出信息字符串</param>
        /// <param name="len">输出信息字符串长度</param>
        /// <returns>0：成功，1：执行失败，2：执行超时。（65535：无效值）</returns>
        [DllImport("RobotAPI.dll", EntryPoint = "rokae_last_msg", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int rokae_last_msg(ref string msg, ref uint len);


    }
}
